package com.map.core.utils;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.sql.*;
import java.util.ArrayList;

/**
 * 将对应数据库的表名转换成实体类
 * 
 * @author DaiSn
 *
 */
public class GenEntityTool {
	/**
	 * 包名
	 */
	private static final String PACKAGE_ROUTE = "package com.iottepa.modules.jpa.vo.safeprotect;\r\n";
	
	/**
	 * 列名数组
	 */
	private ArrayList<String> colNames = new ArrayList<String>();

	/**
	 * 列名类型数组
	 */
	private ArrayList<String> colType = new ArrayList<String>();

	/**
	 * 列名类型数组
	 */
	private ArrayList<String> colComments = new ArrayList<String>();

	/**
	 * 列名类型数组
	 */
	private static ArrayList<String> tabComments = new ArrayList<String>();
	
	/**
	 * 列名大小数组
	 */
	private int[] colSize;

	/**
	 * 是否需要导入java.util.*
	 */
	private boolean f_util = false;

	/**
	 * 是否需要导入java.sql.*
	 */
	private boolean f_sql = false;

	public GenEntityTool() {
	}

	/**
	 * 构造方法
	 * 
	 * @param tabName
	 */
	public GenEntityTool(String tabName, String tabComment) {

		Connection conn = null;
		String sql = "select * from " + tabName;
		try {
			conn = JDBCUtils.getInstance().getJDBCConnection();
			PreparedStatement prep = conn.prepareStatement(sql);
			ResultSetMetaData rsmd = prep.getMetaData();
			int size = rsmd.getColumnCount();// 共有多少列
			colSize = new int[size];
			for (int i = 0; i < rsmd.getColumnCount(); i++) {
				colNames.add(rsmd.getColumnName(i + 1));

				colType.add(rsmd.getColumnTypeName(i + 1));
				if (colType.get(i).equalsIgnoreCase("date") ||
						colType.get(i).equalsIgnoreCase("datetime")) {
					f_util = true;
				}
				if (colType.get(i).equalsIgnoreCase("text") || colType.get(i).equalsIgnoreCase("image")) {
					f_sql = true;
				}
				colSize[i] = rsmd.getColumnDisplaySize(i + 1);
			}
			colNames = colNamesForJava(colNames);
			String content = parse(tabName, tabComment, colNames, colType, colSize);
			File file = new File("d:\\entity\\" + initCapForName(tabName) + ".java");
			if (!file.exists()) {
				file.getParentFile().mkdirs();
			}
			file.delete();
			file.createNewFile();
			FileWriter fw = new FileWriter(file, true);
			PrintWriter pw = new PrintWriter(fw);
			pw.println(content);
			pw.flush();
			pw.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.close(conn);
		}
	}

	/**
	 * 将数据库列名转换成java字段名
	 * 
	 * @param test
	 * @return
	 */
	private static ArrayList<String> colNamesForJava(ArrayList<String> test) {
		ArrayList<String> ret = new ArrayList<>();
		for (String string : test) {
			if (string.indexOf("_") != -1) {
				int tem = string.indexOf("_");
				String strtmp = (string.substring(0, tem).toLowerCase()
						+ string.substring(tem + 1, tem + 2).toUpperCase() + string.substring(tem + 2).toLowerCase())
								.replace("_", "");
				ret.add(strtmp);
			} else {
				String strtmp = string.toLowerCase();
				ret.add(strtmp);
			}

		}
		return ret;
	}

	/**
	 * 解析处理，生成java实体类主体代码
	 * 
	 * @param tabName
	 * @param colNames
	 * @param colType
	 * @param colSize
	 * @return
	 */
	private String parse(String tabName, String tabComment, ArrayList<String> colNames, ArrayList<String> colType, int[] colSize) {
		System.out.println("1" + tabName);
		StringBuffer sb = new StringBuffer();
		sb.append(PACKAGE_ROUTE);
		if (f_util) {
			sb.append("import java.util.Date;\r\n");
		}
		if (f_sql) {
			sb.append("import java.sql.*;\r\n\r\n\r\n");
		}
		sb.append("/**\r\n").append(" * ").append(tabComment + "\r\n").append(" * @author DaiSn\r\n").append(" */\r\n");
		sb.append("public class " + initCapForName(tabName) + "{\r\n");
		processAllAttrs(sb, tabName);
		processAllMethod(sb);
		sb.append("}\r\n");
		return sb.toString();
	}

	/**
	 * 生成所有的方法
	 * 
	 * @param sb
	 */
	private void processAllMethod(StringBuffer sb) {
		for (int i = 0; i < colNames.size(); i++) {
			sb.append("\r\n\tpublic void set" + initCap(colNames.get(i)) + "(" + sqlType2JavaType(colType.get(i)) + " "
					+ colNames.get(i) + "){\r\n");
			sb.append("\t\tthis." + colNames.get(i) + " = " + colNames.get(i) + ";\r\n");
			sb.append("\t}\r\n");

			sb.append("\tpublic " + sqlType2JavaType(colType.get(i)) + " get" + initCap(colNames.get(i)) + "(){\r\n");
			sb.append("\t\treturn " + colNames.get(i) + ";\r\n");
			sb.append("\t}\r\n");
		}
	}

	/**
	 * 解析输出属性
	 * 
	 * @return
	 */
	private void processAllAttrs(StringBuffer sb, String tabName) {
		colComments = getColumnComments(tabName);
		for (int i = 0; i < colNames.size(); i++) {
			sb.append("\t/**\r\n").append("\t * ").append(colComments.get(i) + "\r\n").append("\t */\r\n");
			sb.append("\tprivate " + sqlType2JavaType(colType.get(i)) + " " + colNames.get(i) + ";\r\n");
		}
	}

	/**
	 * 把输入字符串的首字母变成大写
	 * 
	 * @param str
	 * 
	 * @return
	 * 
	 */
	private String initCap(String str) {
		char[] ch = str.toCharArray();
		if (ch[0] >= 'a' && ch[0] <= 'z') {
			ch[0] = (char) (ch[0] - 32);
		}
		String strtmp = new String(ch);
		if (strtmp.indexOf("_") != -1) {
			int tem = str.indexOf("_");
			String tmp = (strtmp.substring(0, 1) + strtmp.substring(1, tem).toLowerCase()
					+ strtmp.substring(tem + 1, tem + 2).toUpperCase() + strtmp.substring(tem + 2).toLowerCase())
							.replace("_", "");
			return tmp;
		} else {
			return strtmp;
		}
	}
	
	/**
	 * 把输入字符串的首字母变成大写
	 * 
	 * @param str
	 * 
	 * @return
	 * 
	 */
	private String initCapForName(String str) {
		char[] ch = str.toCharArray();
		if (ch[0] >= 'a' && ch[0] <= 'z') {
			ch[0] = (char) (ch[0] - 32);
		}
		String strtmp = new String(ch);
		System.out.println(str + " " + strtmp);
		if (strtmp.indexOf("_") != -1) {
			int tem = strtmp.indexOf("_");
			String tmp = (strtmp.substring(0, 1) + strtmp.substring(1, tem).toLowerCase()
					+ strtmp.substring(tem + 1, tem + 2).toUpperCase() + strtmp.substring(tem + 2).toLowerCase())
							.replace("_", "");
			return tmp;
		} else {
			return strtmp;
		}
	}
	/**
	 * 
	 * @param sqlType
	 * @return
	 */
	private String sqlType2JavaType(String sqlType) {
		if (sqlType.equalsIgnoreCase("bit")) {
			return "boolean";
		} else if (sqlType.equalsIgnoreCase("tinyint")) {
			return "byte";
		} else if (sqlType.equalsIgnoreCase("smallint")) {
			return "short";
		} else if (sqlType.equalsIgnoreCase("int")) {
			return "int";
		} else if (sqlType.equalsIgnoreCase("bigint")) {
			return "long";
		} else if (sqlType.equalsIgnoreCase("float")) {
			return "float";
		} else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric")
				|| sqlType.equalsIgnoreCase("double") || sqlType.equalsIgnoreCase("real")) {
			return "double";
		} else if (sqlType.equalsIgnoreCase("money") || sqlType.equalsIgnoreCase("smallmoney")) {
			return "double";
		} else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char")
				|| sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nchar")) {
			return "String";
		} else if (sqlType.equalsIgnoreCase("datetime") || sqlType.equalsIgnoreCase("date")) {
			return "Date";
		}

		else if (sqlType.equalsIgnoreCase("image")) {
			return "Blob";
		} else if (sqlType.equalsIgnoreCase("text")) {
			return "Clob";
		}
		return null;
	}

	/**
	 * 读取数据库中的表名
	 * 
	 * @return表名的String数组
	 * 
	 */
	private static ArrayList<String> getTabNames() {
		Connection conn = null;
		String sql = "show tables";
		ArrayList<String> tabNames = new ArrayList<>();

		try {
			conn = JDBCUtils.getInstance().getJDBCConnection();
			PreparedStatement prep = conn.prepareStatement(sql);
			ResultSet rs = prep.executeQuery();
			rs.last();
			int size = rs.getRow();
			rs.beforeFirst();
			int i = 0;
			while (rs.next() && i < size) {
				tabNames.add(rs.getString(1));
				i++;
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtils.close(conn);
		}
		return tabNames;
	}

	/**
	 * 获取表的中文名
	 * 
	 * @param con
	 */
	private static ArrayList<String> getTableNotes() {
		Connection conn = JDBCUtils.getInstance().getJDBCConnection();
		String sql = "Select TABLE_COMMENT from INFORMATION_SCHEMA.TABLES Where table_schema = 'test'";
		conn = JDBCUtils.getInstance().getJDBCConnection();
		PreparedStatement prep;
		try {
			prep = conn.prepareStatement(sql);
			ResultSet rs = prep.executeQuery();
			while (rs.next()) {
				tabComments.add(rs.getString("TABLE_COMMENT"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return tabComments;
		
	}

	/**
	 * 获取表中字段的所有注释
	 * 
	 * @param tableName
	 * @return
	 */
	public static ArrayList<String> getColumnComments(String tableName) {
		// 与数据库的连接
		Connection conn = JDBCUtils.getInstance().getJDBCConnection();
		PreparedStatement pStemt = null;
		String tableSql = "select * from " + tableName;
		// 列名注释集合
		ArrayList<String> columnComments = new ArrayList<>();
		ResultSet rs = null;
		try {
			pStemt = conn.prepareStatement(tableSql);
			rs = pStemt.executeQuery("show full columns from " + tableName);
			while (rs.next()) {
				columnComments.add(rs.getString("Comment"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (rs != null) {
				try {
					rs.close();
					JDBCUtils.close(conn);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		return columnComments;
	}

	public static void main(String[] args) {
		ArrayList<String> tabNames = getTabNames();
		ArrayList<String> tabComment = getTableNotes();
		for (int i = 0; i < tabNames.size(); i++) {
			new GenEntityTool(tabNames.get(i), tabComment.get(i));
		}
		for (String string : tabNames) {
			System.out.println(string);
		}
	}
}
